﻿using Hangfire;
using Hangfire.LiteDB;
using Hangfire.Redis;
using Common;
using Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Serilog;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using WebMarkupMin.AspNetCore2;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.OpenApi.Models;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Threading.Tasks;


namespace Web
{
  public class BrotliCompressionProvider : Microsoft.AspNetCore.ResponseCompression.ICompressionProvider
  {
    public string EncodingName => "br";
    public bool SupportsFlush => true;
    public Stream CreateStream(Stream outputStream) => new BrotliStream(outputStream, CompressionMode.Compress);
  }

  public class Startup
  {
    public IWebHostEnvironment HostEnvironment { get; }
    public IConfiguration Configuration { get; private set; }

    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
      Configuration = configuration;
      HostEnvironment = env;
      ConfigurationManager.Configuration = configuration;
      Log.Logger = new LoggerConfiguration()
           .ReadFrom.Configuration(configuration)
           .Enrich.FromLogContext()
           .CreateLogger();
    }

    public void ConfigureServices(IServiceCollection services)
    {

      MyHttpContext.Init(services);

      services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
      MyHttpContext.serviceCollection = services;

      services.AddControllers();

      var builder = services.AddControllersWithViews();
      var isDev = !HostEnvironment.IsProduction();
#if DEBUG
      if (!HostEnvironment.IsProduction())
      {
        builder.AddRazorRuntimeCompilation();
      }
#endif

      services.AddControllersWithViews().AddNewtonsoftJson();
      services.AddSwaggerGen(opt =>
      {
        opt.CustomSchemaIds(x => x.FullName);
        opt.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPI", Version = "v1", Description = "宝鸡检测监管APP接口" });

        var securityScheme = new OpenApiSecurityScheme
        {
          Name = "JWT Authentication",
          Description = "宝鸡检测监管APP接口",
          In = ParameterLocation.Header,
          Type = SecuritySchemeType.Http,
          Scheme = "Bearer",
          BearerFormat = "JWT",
          Reference = new OpenApiReference
          {
            Id = JwtBearerDefaults.AuthenticationScheme,
            Type = ReferenceType.SecurityScheme
          }
        };
        opt.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);

        opt.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                { securityScheme, new string[] { } }
            });
#if DEBUG
        var _path = AppDomain.CurrentDomain.BaseDirectory.Split("Web")[0];
        opt.IncludeXmlComments(Path.Combine(_path, $"./web/App_Data/controllers.xml"));
#endif
      });


      ////代码优化处理
      //services.AddWebMarkupMin(options =>
      //{
      //  options.AllowCompressionInDevelopmentEnvironment = false; //开发环境不压缩 
      //  options.AllowMinificationInDevelopmentEnvironment = false; //开发环境不精简
      //  options.DisablePoweredByHttpHeaders = true;
      //  //options.DisableCompression = true;
      //})
      //.AddHtmlMinification(options => //代码精简配置
      //{
      //  //options.MinificationSettings.RemoveRedundantAttributes = true;
      //  //options.MinificationSettings.RemoveHttpProtocolFromAttributes = true;
      //  //options.MinificationSettings.RemoveHttpsProtocolFromAttributes = true;
      //  options.MinificationSettings.MinifyEmbeddedCssCode = false;
      //  //options.MinificationSettings.RemoveOptionalEndTags = false;
      //});
      ////响应压缩处理
      //services.AddResponseCompression(options =>
      //{
      //  options.Providers.Add<BrotliCompressionProvider>();
      //  options.EnableForHttps = true;
      //  options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] {
      //              "application/xhtml+xml",
      //              "application/atom+xml",
      //              "image/svg+xml",
      //    });
      //});
      //压缩级别
      //services.Configure<GzipCompressionProviderOptions>(options =>
      //{
      //  options.Level = CompressionLevel.Fastest;
      //});
      //services.AddResponseCaching();
      ////services.AddDistributedMemoryCache();
      //services.AddRazorPages(config =>
      //{
      //});
      //services.AddMemoryCache();//使用本地缓存必须添加
      //services.AddSession();//使用Session
      //services.AddSignalR();//使用 SignalR
      services.Configure<SystemConfig>(Configuration.GetSection("SiteConfig"));      

      //services.Configure<HangfireSetting>(Configuration.GetSection("HangfireSetting"));

      //services.AddHangfire(configuration =>
      //{
      //  var settingsSection = Configuration.GetSection("HangfireSetting");
      //  var hangfireSetting = settingsSection.Get<HangfireSetting>();
      //  if (hangfireSetting != null)
      //  {
      //    if (string.IsNullOrEmpty(hangfireSetting.RedisConnStr))
      //    {
      //      hangfireSetting.RedisConnStr = "localhost";
      //    }
      //    RedisStorageOptions redisStorageOptions = new RedisStorageOptions();
      //    if (!string.IsNullOrEmpty(hangfireSetting.RedisPrefix))
      //    {
      //      redisStorageOptions.Prefix = hangfireSetting.RedisPrefix;
      //    }
      //    if (hangfireSetting.RedisDb > 0)
      //    {
      //      redisStorageOptions.Db = hangfireSetting.RedisDb;
      //    }
      //    Log.Information("Hangfire 使用 Redis 配置：{0}，Prefix：{1}", hangfireSetting.RedisConnStr, hangfireSetting.RedisPrefix);
      //    configuration.UseRedisStorage(hangfireSetting.RedisConnStr, redisStorageOptions);
      //  }
      //  else
      //  {
      //    Log.Information("Hangfire 使用 LiteDB");
      //    configuration.UseLiteDbStorage();
      //  }
      //  //configuration.UseMemoryStorage();
      //});
      Log.Information("ConfigureServices 完成");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
          IOptions<SystemConfig> systemConfig)
    {

      HttpUseExceptionHandler.Init(app, new List<string> { "index.html" });
      app.UseStaticFiles();
      //app.UseEnableRequestRewind();
      if (!env.IsProduction())
      {
        Log.Information("开发模式");
        app.UseExceptionHandler("/Home/Error");
        //app.UseDeveloperExceptionPage();
      }
      else
      {
        Log.Information("生产模式");
        app.UseExceptionHandler("/Home/Error");
        app.UseResponseCaching();
      }

      #region Hangfire 配置
      //var options = new BackgroundJobServerOptions
      //{
      //  WorkerCount = Environment.ProcessorCount * 5, //并发任务数
      //  ServerName = string.Format("{0} ({1})", systemConfig.Value.Name, systemConfig.Value.Domain),//服务器名称
      //  Queues = new[] { "test", "default" },//队列名称，只能为小写
      //  ShutdownTimeout = TimeSpan.FromHours(24)
      //};

      //app.UseHangfireServer(options);//启动Hangfire服务
      //var options2 = new DashboardOptions
      //{
      //  Authorization = new[] { HangfireAuthorizationFilter.Create("xiaox") }
      //};
      //app.UseHangfireDashboard("/hangfire", options2);

      //GlobalJobFilters.Filters.Add(new LogEverythingAttribute());


      //RecurringJob.AddOrUpdate(() => MpToken.RefreshToken1(), $"* 10/1 * * * ?");
      #endregion

      #region Senparc 配置

      //IRegisterService register = RegisterService.Start(senparcSetting.Value).UseSenparcGlobal();
      ////register.ChangeDefaultCacheNamespace("DefaultCO2NETCache");
      //register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value)
      //        .RegisterThreads();
      //var weiXinConfig = ConfigBiz.GetWeiXinConfig();
      //if (senparcWeixinSetting.Value != null)
      //{
      //    if (!string.IsNullOrEmpty(senparcWeixinSetting.Value.WeixinAppId) && !string.IsNullOrEmpty(senparcWeixinSetting.Value.WeixinAppSecret))
      //    {
      //        register.RegisterMpAccount(senparcWeixinSetting.Value, SiteConfig.Current.Name);
      //    }
      //    else
      //    {
      //        if (SiteConfig.CurrentRunMode == RunMode.MP)
      //        {
      //            Log.Error("没有配置 AppId 和 AppSecret");
      //        }
      //    }
      //    if (!string.IsNullOrEmpty(senparcWeixinSetting.Value.WeixinCorpId) && !string.IsNullOrEmpty(senparcWeixinSetting.Value.WeixinCorpSecret))
      //    {
      //        register.RegisterWorkAccount(senparcWeixinSetting.Value, SiteConfig.Current.Name);
      //    }
      //    else
      //    {
      //        if (SiteConfig.CurrentRunMode == RunMode.Work)
      //        {
      //            Log.Error("没有配置 CorpId 和 CorpSecret");
      //        }
      //    }
      //}
      #endregion

      //app.UseEnableRequestRewind();
      //app.UseResponseCompression();
      //app.UseWebMarkupMin();
      //app.UseCookiePolicy();
      //app.UseSession();
      //app.UseMiddleware<RouteDefend>();
      app.UseRouting();
      app.UseCors();
      app.UseAuthentication();
      app.UseAuthorization();

      app.UseEndpoints(endpoints =>
      {
        //特性路由(WebApi)
        endpoints.MapControllers();
        //控制器路由(MVC)
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
      });
      //app.UseSerilogRequestLogging();
      Log.Information("Configure 完成");
      Log.Information("当前运行环境：{0}", env.EnvironmentName);
      Log.Information("系统当前目录：{0}", env.ContentRootPath);
      Log.Information("网站页面路径：{0}", env.WebRootPath);
    }

  }
}
